package com.mopencode.seckill.task;

import com.lxs.legou.common.utils.IdWorker;
import com.lxs.legou.common.utils.SystemConstants;
import com.mopencode.seckill.dao.SeckillGoodsDao;
import com.mopencode.seckill.po.SeckillGoods;
import com.mopencode.seckill.po.SeckillOrder;
import com.mopencode.seckill.pojo.SeckillStatus;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Mcb
 * @date 2022/4/10
 * @apiNote 多线程下单
 */
@Component
public class MultiThreadingCreateOrder {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private SeckillGoodsDao seckillGoodsDao;
    @Autowired
    private RedissonClient redissonClient;

    @Async
    public void createOrder(){
        //排队，按顺序从缓存中取出
        SeckillStatus seckillStatus = (SeckillStatus)redisTemplate.boundListOps(SystemConstants.SEC_KILL_USER_QUEUE_KEY).rightPop();
        if (seckillStatus != null){
            String time = seckillStatus.getTime();
            long goodsId = seckillStatus.getGoodsId();
            String userId = seckillStatus.getUsername();

            RLock lock = redissonClient.getLock("seckillstock" + goodsId);

            try {
                //waitTime：等待锁的时间
                //leaseTime：所得持有时间
                lock.tryLock(20,20, TimeUnit.SECONDS);

                SeckillGoods seckillGoods = (SeckillGoods) redisTemplate.boundHashOps(SystemConstants.SEC_KILL_GOODS_PREFIX + time).get(goodsId);
                if (null == seckillGoods) {
                    throw new RuntimeException("已售罄");
                }

                SeckillOrder seckillOrder = new SeckillOrder();
                seckillOrder.setSeckillId(idWorker.nextId());
                seckillOrder.setUserId(userId);
                seckillOrder.setCreateTime(new Date());
                seckillOrder.setStatus("0");
                seckillOrder.setMoney(seckillGoods.getPrice());
                //将秒杀订单存入redis中
                redisTemplate.boundHashOps(SystemConstants.SEC_KILL_ORDER_KEY).put(userId, seckillOrder);
                //库存减一
                seckillGoods.setStockCount(seckillGoods.getStockCount() - 1);

                if (seckillGoods.getStockCount() <= 0) {
                    //将商品数据同步到数据库中
                    seckillGoodsDao.updateById(seckillGoods);
                    //清除redis缓存
                    redisTemplate.boundHashOps(SystemConstants.SEC_KILL_GOODS_PREFIX + time).delete(goodsId);
                }else {
                    redisTemplate.boundHashOps(SystemConstants.SEC_KILL_GOODS_PREFIX + time).put(goodsId, seckillGoods);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }

}
